/*
 * STMicroelectronics SensorHAL core
 *
 * Version 3.1.5
 * Copyright 2015-2016 STMicroelectronics Inc.
 * Author: Denis Ciocca - <denis.ciocca@st.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 */

#define __STDC_LIMIT_MACROS
#define __STDINT_LIMITS

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <endian.h>
#include <unistd.h>
#include <memory>

#include <STMSensorsList.h>
#include "sensors_legacy.h"
#include "SensorHAL.h"
#include "Accelerometer.h"
#include "Magnetometer.h"
#include "Gyroscope.h"
#include "StepDetector.h"
#include "StepCounter.h"
#include "SignificantMotion.h"

#include "TiltSensor.h"
#include "SWMagnetometerUncalibrated.h"
#include "SWGyroscopeUncalibrated.h"
#include "SWAccelerometerUncalibrated.h"
#include "Pressure.h"
#include "RHumidity.h"
#include "Temp.h"
#include "SWAccelMagnFusion6X.h"
#include "SWGeoMagRotationVector.h"
#include "SWAccelGyroFusion6X.h"
#include "SWGameRotationVector.h"
#include "SWAccelMagnGyroFusion9X.h"
#include "SWRotationVector.h"
#include "SWOrientation.h"
#include "SWGravity.h"
#include "SWLinearAccel.h"
#include "SWVirtualGyroscope.h"
#include "WristTiltGesture.h"
#include "Gesture.h"
#include "DeviceOrientation.h"

#ifdef CONFIG_ST_HW_FUSION_ENABLED
#ifdef CONFIG_ST_HAL_9X_RV_ENABLED
#include "RotationVector.h"
#endif /* CONFIG_ST_HAL_9X_RV_ENABLED */

#ifdef CONFIG_ST_HW_GEOMAG_RV_ENABLED
#include "GeomagVector.h"
#endif /* CONFIG_ST_HW_GEOMAG_RV_ENABLED */

#ifdef CONFIG_ST_HW_GAME_RV_ENABLED
#include "GameVector.h"
#endif /* CONFIG_ST_HW_GEOMAG_RV_ENABLED */

#ifdef CONFIG_ST_HW_GRAVITY_ENABLED
#include "Gravity.h"
#endif /* CONFIG_ST_HW_GRAVITY_ENABLED */
#endif /* CONFIG_ST_HW_FUSION_ENABLED */

#ifdef CONFIG_ST_HAL_DYNAMIC_SENSOR
#include "DynamicSensorProxy.h"
#endif /* CONFIG_ST_HAL_DYNAMIC_SENSOR */

#ifdef CONFIG_ST_HAL_DIRECT_REPORT_SENSOR
#include <vector>
#include "RingBuffer.h"

/* Maps sensor_handle=>(channel_handle, rate_level) */
std::unordered_map<int, std::unordered_map<int, int>> mSensorToChannel;

/* Maps channel_handle=>ptr of Channel obj */
std::unordered_map<int, std::unique_ptr<DirectChannelBase>> mDirectChannel;
#endif /* CONFIG_ST_HAL_DIRECT_REPORT_SENSOR */

/*
 * STSensorHAL_iio_devices_data: informations related to the IIO devices, used during open-sensor function
 * @iio_sysfs_path: IIO device sysfs path.
 * @device_name: IIO device name.
 * @android_name: name showed in Android OS.
 * @dev_id: iio:device device id.
 * @sensor_type: Android sensor type.
 * @wake_up_sensor: is a wake-up sensor.
 * @num_channels: number of channels.
 * @channels: channels data.
 * @sa: scale factors available.
 * @hw_fifo_len: hw FIFO length.
 * @power_consumption: sensor power consumption in mA.
 * @sfa: sampling frequency available.
 */
struct STSensorHAL_iio_devices_data {
	char *iio_sysfs_path;
	char *device_name;
	char *android_name;
	unsigned int dev_id;
	int sensor_type;

	bool wake_up_sensor;

	int num_channels;
	struct device_iio_info_channel *channels;
	struct device_iio_scales sa;

	unsigned int hw_fifo_len;
	float power_consumption;

	struct device_iio_sampling_freqs sfa;
} typedef STSensorHAL_iio_devices_data;

/*
 * ST_sensors_supported: ST sensors data used for discovery procedure
 * @driver_name: IIO device name.
 * @android_name: name showed in Android OS.
 * @sensor_type: Android sensor type.
 * @power_consumption: sensor power consumption in mA.
 */
static const struct ST_sensors_supported {
	const char *driver_name;
	const char *android_name;
	int android_sensor_type;
	device_iio_chan_type_t iio_sensor_type;
	float power_consumption;
} ST_sensors_supported[] = {
/**************** Accelerometer sensors ****************/
#ifdef CONFIG_ST_HAL_ACCEL_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "Test Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DS3 Accelerometer Sensor", 240E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLHC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_3, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303DLHC Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLHC_ENABLED */
#ifdef CONFIG_ST_HAL_LIS3DHH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_37, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS3DHH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS3DHH_ENABLED */
#ifdef CONFIG_ST_HAL_IIS3DHHC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_45, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "IIS3DHHC Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_IIS3DHHC_ENABLED */
#ifdef CONFIG_ST_HAL_LIS3DH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_4, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS3DH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS3DH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330D_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_5, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM330D Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330D_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330DL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_6, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM330DL Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330DL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_7, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM330DLC Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_LIS331DLH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_8, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS331DLH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS331DLH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_9, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303DL Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_10, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303DLH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_11, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303DLM Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_12, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM330 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AGR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_13, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303AGR Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AGR_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DS12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_14, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS2DS12 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DS12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DG_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_15, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS2DG Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DG_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DSM Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DS33 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DS3H Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM303AH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2HH12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_25, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS2HH12 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2HH12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DW12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_27, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS2DW12 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2HH12_ENABLED */
#ifdef CONFIG_ST_HAL_LSM9DS1_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_29, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM9DS1 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM9DS1_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DSO Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DSL Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_33, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LIS2DH/LIS2DH12 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS0_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_38, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DS0 Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS0_ENABLED */
#ifdef CONFIG_ST_HAL_ISM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_40, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "ISM330DLC Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_IIS2DH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_43, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "IIS2DH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_IIS2DH_ENABLED */
#ifdef CONFIG_ST_HAL_ISM303DAC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_44, SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "ISM303DAC Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM303DAC_ENABLED */
#ifdef CONFIG_ST_HAL_ASM330LHH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_32, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "ASM330LHH Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ASM330LHH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ACCEL_NAME_SUFFIX_IIO), SENSOR_TYPE_ACCELEROMETER, DEVICE_IIO_ACC, "LSM6DSR Accelerometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_ACCEL_ENABLED */

/**************** Magnetometer sensors ****************/
#ifdef CONFIG_ST_HAL_MAGN_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "Test Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DS3 Magnetometer Sensor", 2.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LIS3MDL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_2, SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LIS3MDL Magnetometer Sensor", 2.0f)
#endif /* CONFIG_ST_HAL_LIS3MDL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLHC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_3, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303DLHC Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLHC_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_9, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303DL Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_10, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303DLH Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303DLM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_11, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303DLM Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303DLM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AGR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_13, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303AGR Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AGR_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DSM Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DS3H Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM303AH Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2MDL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_28, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LIS2MDL Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2MDL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM9DS1_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_29, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM9DS1 Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM9DS1_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DSO Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DSL Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_ISM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_40, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "ISM330DLC Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_IIS2MDC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_42, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "IIS2MDC Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_IIS2MDC_ENABLED */
#ifdef CONFIG_ST_HAL_ISM303DAC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_44, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "ISM303DAC Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM303DAC_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, MAGN_NAME_SUFFIX_IIO), SENSOR_TYPE_GEOMAGNETIC_FIELD, DEVICE_IIO_MAGN, "LSM6DSR Magnetometer Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_MAGN_ENABLED */

/**************** Gyroscope sensors ****************/
#ifdef CONFIG_ST_HAL_GYRO_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "Test Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DS3 Gyroscope Sensor", 1.25f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330D_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_5, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM330D Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330D_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330DL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_6, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM330DL Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330DL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_7, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM330DLC Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_LSM330_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_12, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM330 Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM330_ENABLED */
#ifdef CONFIG_ST_HAL_L3G4200D_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_16, SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "L3G4200D Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_L3G4200D_ENABLED */
#ifdef CONFIG_ST_HAL_L3GD20_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_17, SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "L3GD20 Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_L3GD20_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DSM Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DS33 Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DS3H Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM9DS1_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_29, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM9DS1 Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM9DS1_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DSO Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DSL Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS0_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_38, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DS0 Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS0_ENABLED */
#ifdef CONFIG_ST_HAL_ISM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_40, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "ISM330DLC Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_ASM330LHH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_32, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "ASM330LHH Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ASM330LHH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, GYRO_NAME_SUFFIX_IIO), SENSOR_TYPE_GYROSCOPE, DEVICE_IIO_GYRO, "LSM6DSR Gyroscope Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_GYRO_ENABLED */

/**************** Step Detector sensors ****************/
#ifdef CONFIG_ST_HAL_STEP_DETECTOR_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "Test Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DS3 Step Detector Sensor", 240E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DS12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_14, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LIS2DS12 Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DS12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DG_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_15, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LIS2DG Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DG_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DSM Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DS33 Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DS3H Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM303AH Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DSO Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DSL Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, STEP_DETECTOR_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_DETECTOR, DEVICE_IIO_STEP_DETECTOR, "LSM6DSR Step Detector Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_STEP_DETECTOR_ENABLED */

/**************** Step Counter sensors ****************/
#ifdef CONFIG_ST_HAL_STEP_COUNTER_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "Test Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DS3 Step Counter Sensor", 240E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DS12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_14, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LIS2DS12 Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DS12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DG_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_15, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LIS2DG Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DG_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DSM Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DS33 Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DS3H Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM303AH Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DSO Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DSL Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, STEP_COUNTER_NAME_SUFFIX_IIO), SENSOR_TYPE_STEP_COUNTER, DEVICE_IIO_STEP_COUNTER, "LSM6DSR Step Counter Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_STEP_COUNTER_ENABLED */

/**************** Significant Motion sensors ****************/
#ifdef CONFIG_ST_HAL_SIGN_MOTION_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "Test Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DS3 Significant Motion Sensor", 240E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DS12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_14, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LIS2DS12 Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DS12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DG_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_15, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LIS2DG Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DG_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DSM Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DS33 Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DS3H Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM303AH Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DSO Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DSL Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, SIGN_MOTION_NAME_SUFFIX_IIO), SENSOR_TYPE_SIGNIFICANT_MOTION, DEVICE_IIO_SIGN_MOTION, "LSM6DSR Significant Motion Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_SIGN_MOTION_ENABLED */

/**************** Tilt sensors ****************/
#ifdef CONFIG_ST_HAL_TILT_ENABLED
#ifdef CONFIG_ST_HAL_TEST_SENSORS_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_0, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "Test Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_TEST_SENSORS_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DS3 Tilt Sensor", 240E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DS12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_14, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LIS2DS12 Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DS12_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DG_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_15, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LIS2DG Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LIS2DG_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSM_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DSM Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSM_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS33_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_21, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DS33 Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS33_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DS3H Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM303AH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_23, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM303AH Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM303AH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DSO Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSL_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_31, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DSL Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSL_ENABLED */
#ifdef CONFIG_ST_HAL_ISM330DLC_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_20, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "ISM330DLC Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ISM330DLC_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, TILT_NAME_SUFFIX_IIO), SENSOR_TYPE_TILT_DETECTOR, DEVICE_IIO_TILT, "LSM6DSR Tilt Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_TILT_ENABLED */

/**************** Wrist Tilt Gesture ****************/
#ifdef CONFIG_ST_HAL_WRIST_TILT_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, WRIST_GESTURE_NAME_SUFFIX_IIO), SENSOR_TYPE_WRIST_TILT_GESTURE, DEVICE_IIO_WRIST_TILT_GESTURE, "LSM6DS3H Wrist Tilt Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, WRIST_GESTURE_NAME_SUFFIX_IIO), SENSOR_TYPE_WRIST_TILT_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSO Wrist Tilt Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, WRIST_GESTURE_NAME_SUFFIX_IIO), SENSOR_TYPE_WRIST_TILT_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSR Wrist Tilt Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_WRIST_TILT_GESTURE_ENABLED */

/**************** Glance Gesture ****************/
#ifdef CONFIG_ST_HAL_GLANCE_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, GLANCE_GESTURE_NAME_SUFFIX_IIO), SENSOR_TYPE_GLANCE_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSO Glance Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, GLANCE_GESTURE_NAME_SUFFIX_IIO), SENSOR_TYPE_GLANCE_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSR Glance Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_GLANCE_GESTURE_ENABLED */

/**************** WakeUp Gesture ****************/
#ifdef CONFIG_ST_HAL_WAKEUP_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ST_HAL_WAKEUP_SUFFIX_IIO), SENSOR_TYPE_WAKE_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSO WakeUp Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LIS2DW12_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_27, ST_HAL_WAKEUP_SUFFIX_IIO), SENSOR_TYPE_WAKE_GESTURE, DEVICE_IIO_GESTURE, "LIS2MDL WakeUp Gesture", 0.0f)
#endif
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ST_HAL_WAKEUP_SUFFIX_IIO), SENSOR_TYPE_WAKE_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSR WakeUp Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_WAKEUP_GESTURE_ENABLED */

/**************** PickUp Gesture ****************/
#ifdef CONFIG_ST_HAL_PICKUP_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ST_HAL_PICKUP_SUFFIX_IIO), SENSOR_TYPE_PICK_UP_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSO PickUp Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ST_HAL_PICKUP_SUFFIX_IIO), SENSOR_TYPE_PICK_UP_GESTURE, DEVICE_IIO_GESTURE, "LSM6DSR PickUp Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_PICKUP_GESTURE_ENABLED */

#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_NOUGAT_VERSION)
/**************** Motion Gesture ****************/
#ifdef CONFIG_ST_HAL_MOTION_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ST_HAL_MOTION_SUFFIX_IIO), SENSOR_TYPE_MOTION_DETECT, DEVICE_IIO_GESTURE, "LSM6DSO Motion Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ST_HAL_MOTION_SUFFIX_IIO), SENSOR_TYPE_MOTION_DETECT, DEVICE_IIO_GESTURE, "LSM6DSR Motion Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_MOTION_GESTURE_ENABLED */

/**************** No-Motion Gesture ****************/
#ifdef CONFIG_ST_HAL_NO_MOTION_GESTURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ST_HAL_NO_MOTION_SUFFIX_IIO), SENSOR_TYPE_STATIONARY_DETECT, DEVICE_IIO_GESTURE, "LSM6DSO No-Motion Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ST_HAL_NO_MOTION_SUFFIX_IIO), SENSOR_TYPE_STATIONARY_DETECT, DEVICE_IIO_GESTURE, "LSM6DSR No-Motion Gesture", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_NO_MOTION_GESTURE_ENABLED */

/**************** Orientation ****************/
#ifdef CONFIG_ST_HAL_DEVICE_ORIENTATION_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, ST_HAL_DEVICE_ORIENTATION_SUFFIX_IIO), SENSOR_TYPE_DEVICE_ORIENTATION, DEVICE_IIO_GESTURE, "LSM6DSO Device Orientation Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, ST_HAL_DEVICE_ORIENTATION_SUFFIX_IIO), SENSOR_TYPE_DEVICE_ORIENTATION, DEVICE_IIO_GESTURE, "LSM6DSR Device Orientation Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_DEVICE_ORIENTATION_ENABLED */
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */

/**************** Pressure sensors ****************/
#ifdef CONFIG_ST_HAL_PRESSURE_ENABLED
#ifdef CONFIG_ST_HAL_LSM6DS3_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_1, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LSM6DS3 Pressure Sensor", 40E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3_ENABLED */
#ifdef CONFIG_ST_HAL_LPS331AP_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_18, SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS331AP Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS331AP_ENABLED */
#ifdef CONFIG_ST_HAL_LPS25H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(ST_SENSORS_LIST_19, SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS25H Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS25H_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DS3H_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_22, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LSM6DS3H Pressure Sensor", 40E-3f)
#endif /* CONFIG_ST_HAL_LSM6DS3H_ENABLED */
#ifdef CONFIG_ST_HAL_LPS33HW_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_34, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS33HW Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS33HW_ENABLED */
#ifdef CONFIG_ST_HAL_LPS35HW_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_35, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS35HW Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS35HW_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HD_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_36, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS22HD Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HD_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HB_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_24, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS22HB Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HB_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_41, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LPS22HH Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HH_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSO_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_30, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LSM6DSO Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSO_ENABLED */
#ifdef CONFIG_ST_HAL_LSM6DSR_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_46, PRESSURE_NAME_SUFFIX_IIO), SENSOR_TYPE_PRESSURE, DEVICE_IIO_PRESSURE, "LSM6DSR Pressure Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LSM6DSR_ENABLED */
#endif /* CONFIG_ST_HAL_PRESSURE_ENABLED */

/**************** RHumidity sensors ****************/
#ifdef CONFIG_ST_HAL_RHUMIDITY_ENABLED
#ifdef CONFIG_ST_HAL_HTS221_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_26, RHUMIDITY_NAME_SUFFIX_IIO), SENSOR_TYPE_RELATIVE_HUMIDITY, DEVICE_IIO_HUMIDITYRELATIVE, "HTS221 RHumidity Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_HTS221_ENABLED */
#endif /* CONFIG_ST_HAL_RHUMIDITY_ENABLED */

/**************** Temperature sensors ****************/
#ifdef CONFIG_ST_HAL_TEMP_ENABLED
#ifdef CONFIG_ST_HAL_LPS33HW_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_34, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP,"LPS33HW Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS33HW_ENABLED */
#ifdef CONFIG_ST_HAL_LPS35HW_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_35, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP,"LPS35HW Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS35HW_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HD_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_36, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP,"LPS22HD Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HD_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HB_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_24, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP,"LPS22HB Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HB_ENABLED */
#ifdef CONFIG_ST_HAL_LPS22HH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_41, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP,"LPS22HH Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_LPS22HH_ENABLED */
#ifdef CONFIG_ST_HAL_HTS221_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_26, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP, "HTS221 Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_HTS221_ENABLED */
#ifdef CONFIG_ST_HAL_ASM330LHH_ENABLED
	ST_HAL_NEW_SENSOR_SUPPORTED(CONCATENATE_STRING(ST_SENSORS_LIST_32, TEMP_NAME_SUFFIX_IIO), SENSOR_TYPE_TEMPERATURE, DEVICE_IIO_TEMP, "ASM330LHH Temperature Sensor", 0.0f)
#endif /* CONFIG_ST_HAL_ASM330LHH_ENABLED */
#endif /* CONFIG_ST_HAL_TEMP_ENABLED */
};

/*
 * ST_virtual_sensors_list: ST virtual sensors available
 * @sensor_type: Android sensor type.
 */
static const struct ST_virtual_sensors_list {
	int android_sensor_type;
} ST_virtual_sensors_list[] = {
{ .android_sensor_type = 101010 },
#ifdef ST_HAL_NEEDS_GEOMAG_FUSION
	{ .android_sensor_type = SENSOR_TYPE_ST_ACCEL_MAGN_FUSION6X },
#endif /* ST_HAL_NEEDS_GEOMAG_FUSION */
#ifdef CONFIG_ST_HAL_MAGN_UNCALIB_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED },
#endif /* CONFIG_ST_HAL_MAGN_UNCALIB_AP_ENABLED */
#ifdef CONFIG_ST_HAL_VIRTUAL_GYRO_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_GYROSCOPE },
#endif /* CONFIG_ST_HAL_VIRTUAL_GYRO_ENABLED */
#ifdef CONFIG_ST_HAL_GYRO_UNCALIB_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED },
#endif /* CONFIG_ST_HAL_GYRO_UNCALIB_AP_ENABLED */
#ifdef CONFIG_ST_HAL_GEOMAG_ROT_VECTOR_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR },
#endif /* CONFIG_ST_HAL_GEOMAG_ROT_VECTOR_AP_ENABLED */
#ifdef ST_HAL_NEEDS_6AX_FUSION
	{ .android_sensor_type = SENSOR_TYPE_ST_ACCEL_GYRO_FUSION6X },
#endif /* ST_HAL_NEEDS_6AX_FUSION */
#ifdef CONFIG_ST_HAL_GAME_ROT_VECTOR_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_GAME_ROTATION_VECTOR },
#endif /* CONFIG_ST_HAL_GAME_ROT_VECTOR_AP_ENABLED */
#ifdef ST_HAL_NEEDS_9AX_FUSION
	{ .android_sensor_type = SENSOR_TYPE_ST_ACCEL_MAGN_GYRO_FUSION9X },
#endif /* ST_HAL_NEEDS_9AX_FUSION */
#ifdef CONFIG_ST_HAL_ROT_VECTOR_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_ROTATION_VECTOR },
#endif /* CONFIG_ST_HAL_ROT_VECTOR_AP_ENABLED */
#ifdef CONFIG_ST_HAL_ORIENTATION_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_ORIENTATION },
#endif /* CONFIG_ST_HAL_ORIENTATION_AP_ENABLED */
#ifdef CONFIG_ST_HAL_GRAVITY_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_GRAVITY },
#endif /* CONFIG_ST_HAL_GRAVITY_AP_ENABLED */
#ifdef CONFIG_ST_HAL_LINEAR_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_LINEAR_ACCELERATION },
#endif /* CONFIG_ST_HAL_LINEAR_AP_ENABLED */
#ifdef CONFIG_ST_HAL_ACCEL_UNCALIB_AP_ENABLED
	{ .android_sensor_type = SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED },
#endif /* CONFIG_ST_HAL_ACCEL_UNCALIB_AP_ENABLED */
};

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
#define ST_HAL_PRIVATE_DATA_CALIBRATION_LM_ACCEL_ID		(0)
#define ST_HAL_PRIVATE_DATA_CALIBRATION_LM_MAGN_ID		(1)
#define ST_HAL_PRIVATE_DATA_CALIBRATION_LM_GYRO_ID		(2)
#define ST_HAL_PRIVATE_DATA_CALIBRATION_LM_MAX_ID		(3)

/*
 * st_hal_private_data: private data structure
 * @calibration_last_modification: time_t infomations about last calibration modification.
 */
struct st_hal_private_data {
	time_t calibration_last_modification[ST_HAL_PRIVATE_DATA_CALIBRATION_LM_MAX_ID];
};
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */

#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_MARSHMALLOW_VERSION)
static int st_hal_set_operation_mode(unsigned int mode);
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */

/*
 * st_hal_create_virtual_class_sensor - Istance virtual sensor class
 * @sensor_type: Android sensor type.
 * @handle: android handle number.
 *
 * Return value: sensor class pointer on success, NULL pointer on fail.
 */
static SensorBase* st_hal_create_virtual_class_sensor(int sensor_type, int handle)
{
	SensorBase *sb = NULL;

	switch (sensor_type) {
#ifdef CONFIG_ST_HAL_VIRTUAL_GYRO_ENABLED
	case SENSOR_TYPE_GYROSCOPE:
		sb = new SWVirtualGyroscope("iNemoEngine Virtual Gyroscope Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_VIRTUAL_GYRO_ENABLED */
#ifdef CONFIG_ST_HAL_MAGN_UNCALIB_AP_ENABLED
	case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
		sb = new SWMagnetometerUncalibrated("Magnetometer Uncalibrated Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_MAGN_UNCALIB_AP_ENABLED */
#ifdef CONFIG_ST_HAL_GYRO_UNCALIB_AP_ENABLED
	case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
		sb = new SWGyroscopeUncalibrated("Gyroscope Uncalibrated Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_GYRO_UNCALIB_AP_ENABLED */
#ifdef ST_HAL_NEEDS_GEOMAG_FUSION
	case SENSOR_TYPE_ST_ACCEL_MAGN_FUSION6X:
		sb = new SWAccelMagnFusion6X("Accel-Magn Fusion 6X", handle);
		break;
#endif /* ST_HAL_NEEDS_GEOMAG_FUSION */
#ifdef CONFIG_ST_HAL_GEOMAG_ROT_VECTOR_AP_ENABLED
	case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
		sb = new SWGeoMagRotationVector("iNemoEngine GeoMagnetic Rotation Vector Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_GEOMAG_ROT_VECTOR_AP_ENABLED */
#ifdef ST_HAL_NEEDS_6AX_FUSION
	case SENSOR_TYPE_ST_ACCEL_GYRO_FUSION6X:
		sb = new SWAccelGyroFusion6X("Accel-Gyro Fusion 6X", handle);
		break;
#endif /* ST_HAL_NEEDS_6AX_FUSION */
#ifdef CONFIG_ST_HAL_GAME_ROT_VECTOR_AP_ENABLED
	case SENSOR_TYPE_GAME_ROTATION_VECTOR:
		sb = new SWGameRotationVector("iNemoEngine Game Rotation Vector Sensor", handle);
		break;
#endif /* SENSOR_TYPE_GAME_ROTATION_VECTOR */
#ifdef ST_HAL_NEEDS_9AX_FUSION
	case SENSOR_TYPE_ST_ACCEL_MAGN_GYRO_FUSION9X:
		sb = new SWAccelMagnGyroFusion9X("Accel-Magn-Gyro Fusion 9X", handle);
		break;
#endif /* ST_HAL_NEEDS_9AX_FUSION */
#ifdef CONFIG_ST_HAL_ROT_VECTOR_AP_ENABLED
	case SENSOR_TYPE_ROTATION_VECTOR:
		sb = new SWRotationVector("iNemoEngine Rotation Vector Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_ROT_VECTOR_AP_ENABLED */
#ifdef CONFIG_ST_HAL_ORIENTATION_AP_ENABLED
	case SENSOR_TYPE_ORIENTATION:
		sb = new SWOrientation("iNemoEngine Orientation Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_ORIENTATION_AP_ENABLED */
#ifdef CONFIG_ST_HAL_GRAVITY_AP_ENABLED
	case SENSOR_TYPE_GRAVITY:
		sb = new SWGravity("iNemoEngine Gravity Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_GRAVITY_AP_ENABLED */
#ifdef CONFIG_ST_HAL_LINEAR_AP_ENABLED
	case SENSOR_TYPE_LINEAR_ACCELERATION:
		sb = new SWLinearAccel("iNemoEngine Linear Acceleration Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_LINEAR_AP_ENABLED */
#ifdef CONFIG_ST_HAL_ACCEL_UNCALIB_AP_ENABLED
	case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
		sb = new SWAccelerometerUncalibrated("Accelerometer Uncalibrated Sensor", handle);
		break;
#endif /* CONFIG_ST_HAL_ACCEL_UNCALIB_AP_ENABLED */
	default:
		(void)handle;
		return NULL;
	}

	return sb->IsValidClass() ? sb : NULL;
}

/*
 * st_hal_create_class_sensor() - Istance hardware sensor class
 * @data: iio:device data.
 * @handle: Android handle number.
 *
 * Return value: sensor class pointer on success, NULL pointer on fail.
 */
static SensorBase* st_hal_create_class_sensor(STSensorHAL_iio_devices_data *data, int handle, void *custom_data)
{
	SensorBase *sb = NULL;
	struct HWSensorBaseCommonData class_data;
#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
	int err;
	struct st_hal_private_data *priv_data = (struct st_hal_private_data *)custom_data;
#else /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
	(void)custom_data;
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */

	if ((strlen(data->iio_sysfs_path) + 1 > HW_SENSOR_BASE_IIO_SYSFS_PATH_MAX) ||
		   (strlen(data->device_name) + 1 > HW_SENSOR_BASE_IIO_DEVICE_NAME_MAX) ||
		   (data->num_channels > HW_SENSOR_BASE_MAX_CHANNELS))
		return NULL;

	memcpy(class_data.device_name, data->device_name, strlen(data->device_name) + 1);
	memcpy(class_data.device_iio_sysfs_path, data->iio_sysfs_path, strlen(data->iio_sysfs_path) + 1);
	memcpy(&class_data.sa, &data->sa, sizeof(class_data.sa));
	memcpy(class_data.channels, data->channels, data->num_channels * sizeof(class_data.channels[0]));

	class_data.device_iio_dev_num = data->dev_id;
	class_data.num_channels = data->num_channels;

	switch (data->sensor_type) {
#ifdef CONFIG_ST_HAL_ACCEL_ENABLED
	case SENSOR_TYPE_ACCELEROMETER:
		sb = new Accelerometer(&class_data, data->android_name, &data->sfa,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
		if (sb->IsValidClass()) {
			err = ((HWSensorBase *)sb)->ApplyFactoryCalibrationData((char *)ST_HAL_FACTORY_ACCEL_DATA_FILENAME, &priv_data->calibration_last_modification[ST_HAL_PRIVATE_DATA_CALIBRATION_LM_ACCEL_ID]);
			if (err < 0)
				ALOGE("\"%s\": Failed to read factory calibration values.", data->android_name);
		}
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
		break;
#endif /* CONFIG_ST_HAL_ACCEL_ENABLED */
#ifdef CONFIG_ST_HAL_MAGN_ENABLED
	case SENSOR_TYPE_MAGNETIC_FIELD:
		sb = new Magnetometer(&class_data, data->android_name, &data->sfa,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
		if (sb->IsValidClass()) {
			err = ((HWSensorBase *)sb)->ApplyFactoryCalibrationData((char *)ST_HAL_FACTORY_MAGN_DATA_FILENAME, &priv_data->calibration_last_modification[ST_HAL_PRIVATE_DATA_CALIBRATION_LM_MAGN_ID]);
			if (err < 0)
				ALOGE("\"%s\": Failed to read factory calibration values.", data->android_name);
		}
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
		break;
#endif /* CONFIG_ST_HAL_MAGN_ENABLED */
#ifdef CONFIG_ST_HAL_GYRO_ENABLED
	case SENSOR_TYPE_GYROSCOPE:
		sb = new Gyroscope(&class_data, data->android_name, &data->sfa,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
		if (sb->IsValidClass()) {
			err = ((HWSensorBase *)sb)->ApplyFactoryCalibrationData((char *)ST_HAL_FACTORY_GYRO_DATA_FILENAME, &priv_data->calibration_last_modification[ST_HAL_PRIVATE_DATA_CALIBRATION_LM_GYRO_ID]);
			if (err < 0)
				ALOGE("\"%s\": Failed to read factory calibration values.", data->android_name);
		}
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
		break;
#endif /* CONFIG_ST_HAL_GYRO_ENABLED */
#ifdef CONFIG_ST_HAL_STEP_DETECTOR_ENABLED
	case SENSOR_TYPE_STEP_DETECTOR:
		sb = new StepDetector(&class_data, data->android_name,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_STEP_DETECTOR_ENABLED */
#ifdef CONFIG_ST_HAL_STEP_COUNTER_ENABLED
	case SENSOR_TYPE_STEP_COUNTER:
		sb = new StepCounter(&class_data, data->android_name,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_STEP_COUNTER_ENABLED */
#ifdef CONFIG_ST_HAL_SIGN_MOTION_ENABLED
	case SENSOR_TYPE_SIGNIFICANT_MOTION:
		sb = new SignMotion(&class_data, data->android_name,
				handle, data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_SIGN_MOTION_ENABLED */
#ifdef CONFIG_ST_HAL_TILT_ENABLED
	case SENSOR_TYPE_TILT_DETECTOR:
		sb = new TiltSensor(&class_data, data->android_name,
				handle, data->hw_fifo_len,
				data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_TILT_ENABLED */
#ifdef CONFIG_ST_HAL_PRESSURE_ENABLED
	case SENSOR_TYPE_PRESSURE:
		sb = new Pressure(&class_data, data->android_name, &data->sfa,
				handle, data->hw_fifo_len,
				data->power_consumption, data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_PRESSURE_ENABLED */
#ifdef CONFIG_ST_HAL_WRIST_TILT_GESTURE_ENABLED
	case SENSOR_TYPE_WRIST_TILT_GESTURE:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_WRIST_TILT_GESTURE_ENABLED */
#ifdef CONFIG_ST_HAL_GLANCE_GESTURE_ENABLED
	case SENSOR_TYPE_GLANCE_GESTURE:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_GLANCE_GESTURE_ENABLED */
#ifdef CONFIG_ST_HAL_WAKEUP_GESTURE_ENABLED
	case SENSOR_TYPE_WAKE_GESTURE:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_WAKEUP_GESTURE_ENABLED */
#ifdef CONFIG_ST_HAL_PICKUP_GESTURE_ENABLED
	case SENSOR_TYPE_PICK_UP_GESTURE:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_PICKUP_GESTURE_ENABLED */
#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_NOUGAT_VERSION)
#ifdef CONFIG_ST_HAL_MOTION_GESTURE_ENABLED
	case SENSOR_TYPE_MOTION_DETECT:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_MOTION_GESTURE_ENABLED */
#ifdef CONFIG_ST_HAL_NO_MOTION_GESTURE_ENABLED
	case SENSOR_TYPE_STATIONARY_DETECT:
		sb = new Gesture(&class_data, data->android_name,
				 handle, data->hw_fifo_len,
				 data->power_consumption);
		break;
#endif /* CONFIG_ST_HAL_NO_MOTION_GESTURE_ENABLED */
#ifdef CONFIG_ST_HAL_DEVICE_ORIENTATION_ENABLED
	case SENSOR_TYPE_DEVICE_ORIENTATION:
		sb = new DeviceOrientation(&class_data, data->android_name,
					   &data->sfa, handle,
					   data->hw_fifo_len,
					   data->power_consumption,
					   data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_DEVICE_ORIENTATION_ENABLED */
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */
#ifdef CONFIG_ST_HAL_RHUMIDITY_ENABLED
	case SENSOR_TYPE_RELATIVE_HUMIDITY:
		sb = new RHumidity(&class_data, data->android_name, &data->sfa,
				   handle, data->hw_fifo_len,
				   data->power_consumption,
				   data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_RHUMIDITY_ENABLED */
#ifdef CONFIG_ST_HAL_TEMP_ENABLED
	case SENSOR_TYPE_TEMPERATURE:
		sb = new Temp(&class_data, data->android_name, &data->sfa,
			      handle, data->hw_fifo_len,
			      data->power_consumption,
			      data->wake_up_sensor);
		break;
#endif /* CONFIG_ST_HAL_TEMP_ENABLED */
	default:
		return NULL;
	}

#ifdef CONFIG_ST_HAL_HAS_SELFTEST_FUNCTIONS
	if (sb->IsValidClass())
		((HWSensorBase *)sb)->GetSelfTestAvailable();
#endif /* CONFIG_ST_HAL_HAS_SELFTEST_FUNCTIONS */

	return sb->IsValidClass() ? sb : NULL;
}

/*
 * st_hal_set_fullscale() - Change fullscale of iio device sensor
 * @iio_sysfs_path: iio device driver sysfs path.
 * @sensor_type: Android sensor type.
 * @sa: scale available structure.
 * @channels: iio channels informations.
 * @num_channels: number of iio channels.
 *
 * Return value: 0 on success, negative number on fail.
 */
static int st_hal_set_fullscale(char *iio_sysfs_path,
		int sensor_type,
		struct device_iio_scales *sa,
		struct device_iio_info_channel *channels,
		int num_channels)
{
	double max_number = 0;
	int err, i, c, max_value;
	device_iio_chan_type_t iio_sensor_type;

	switch (sensor_type) {
#ifdef CONFIG_ST_HAL_ACCEL_ENABLED
	case SENSOR_TYPE_ACCELEROMETER:
		max_value = CONFIG_ST_HAL_ACCEL_RANGE;
		iio_sensor_type = DEVICE_IIO_ACC;
		break;
#endif /* CONFIG_ST_HAL_ACCEL_ENABLED */
#ifdef CONFIG_ST_HAL_MAGN_ENABLED
	case SENSOR_TYPE_MAGNETIC_FIELD:
		max_value = CONFIG_ST_HAL_MAGN_RANGE;
		iio_sensor_type = DEVICE_IIO_MAGN;
		break;
#endif /* CONFIG_ST_HAL_MAGN_ENABLED */
#ifdef CONFIG_ST_HAL_GYRO_ENABLED
	case SENSOR_TYPE_GYROSCOPE:
		max_value = CONFIG_ST_HAL_GYRO_RANGE;
		iio_sensor_type = DEVICE_IIO_GYRO;
		break;
#endif /* CONFIG_ST_HAL_GYRO_ENABLED */
	default:
		return -EINVAL;
	}

	if (channels[0].sign)
		max_number = pow(2, channels[0].bits_used - 1) - 1;
	else
		max_number = pow(2, channels[0].bits_used) - 1;

	for (i = 0; i < (int)sa->length; i++) {
		if ((sa->scales[i] * max_number) >= max_value)
			break;
	}

	if (i == (int)sa->length)
		i = sa->length - 1;

	err = device_iio_utils::set_scale(iio_sysfs_path,
					  sa->scales[i],
					  iio_sensor_type);
	if (err < 0)
		return err;

	for (c = 0; c < num_channels - 1; c++)
		channels[c].scale = sa->scales[i];

	return 0;
}

/*
 * st_hal_load_iio_devices_data() - Read iio devices data from sysfs
 * @data: iio device data.
 *
 * Return value: number of sensors found on success, negative number on fail.
 */
static int st_hal_load_iio_devices_data(STSensorHAL_iio_devices_data *data)
{
	unsigned int index = 0;
	int err, iio_devices_num, i, n;
	struct device_iio_type_name iio_devices[ST_HAL_IIO_MAX_DEVICES];
	IConsole &console { IConsole::getInstance() };

	iio_devices_num =  device_iio_utils::get_devices_name(iio_devices,
							      ST_HAL_IIO_MAX_DEVICES);
	if (iio_devices_num <= 0) {
		console.error("get_device_name return erro");
		return iio_devices_num;
	}

#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_VERBOSE)
	ALOGD("%d IIO devices available into /sys/bus/iio/devices/ folder.", iio_devices_num);
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */

	for (i = 0; i < iio_devices_num; i++) {
		for (n = 0; n < ARRAY_SIZE(ST_sensors_supported); n++) {
			console.info(iio_devices[i].name);
			err = strncmp(iio_devices[i].name, ST_sensors_supported[n].driver_name,
				      strlen(ST_sensors_supported[n].driver_name));
			if (err == 0)
				break;
		}

		if (n == ARRAY_SIZE(ST_sensors_supported)) {
#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_EXTRA_VERBOSE)
			ALOGD("\"%s\": IIO device not supported by sensor HAL.", iio_devices[i].name);
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */
			continue;
		}

		if (strcmp(&iio_devices[i].name[strlen(iio_devices[i].name) -
			   strlen(ST_HAL_WAKEUP_SUFFIX_IIO)], ST_HAL_WAKEUP_SUFFIX_IIO) == 0)
			data[index].wake_up_sensor = true;
		else
			data[index].wake_up_sensor = false;

#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_VERBOSE)
		switch (ST_sensors_supported[n].android_sensor_type) {
			case SENSOR_TYPE_SIGNIFICANT_MOTION:
			case SENSOR_TYPE_TILT_DETECTOR:
				ALOGD("\"%s\": IIO device found and supported.", iio_devices[i].name);
				break;

			default:
				ALOGD("\"%s\": IIO device found and supported. Wake-up sensor: %s",
				      iio_devices[i].name, data[index].wake_up_sensor ? "yes" : "no" );
				break;
		}
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */

		err = asprintf(&data[index].iio_sysfs_path,
			       "/sys/bus/iio/devices/iio:device%d",
			       iio_devices[i].num);
		if (err < 0) {
			continue;
		}

		data[index].power_consumption = ST_sensors_supported[n].power_consumption;

		err = device_iio_utils::scan_channel(data[index].iio_sysfs_path,
						     &data[index].channels,
						     &data[index].num_channels);
		if (err < 0 && err != -ENOENT) {
			ALOGE("\"%s\": failed to read IIO channels informations. (errno: %d)", iio_devices[i].name, err);
			goto st_hal_load_free_iio_sysfs_path;
		}

		err = device_iio_utils::enable_sensor(data[index].iio_sysfs_path, false);
		if (err < 0) {
			ALOGE("\"%s\": failed to disable sensor. (errno: %d)", iio_devices[i].name, err);
			goto st_hal_load_free_iio_channels;
		}

		device_iio_utils::set_clock_type(data[index].iio_sysfs_path, "boottime");

		if (ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_STEP_DETECTOR &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_STEP_COUNTER &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_SIGNIFICANT_MOTION &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_TILT_DETECTOR &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_WRIST_TILT_GESTURE &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_WAKE_GESTURE &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_PICK_UP_GESTURE &&

#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_NOUGAT_VERSION)
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_MOTION_DETECT &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_STATIONARY_DETECT &&
		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_DEVICE_ORIENTATION &&
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */

		    ST_sensors_supported[n].android_sensor_type != SENSOR_TYPE_GLANCE_GESTURE) {
			err = device_iio_utils::get_sampling_frequency_available(data[index].iio_sysfs_path, &data[index].sfa);
			if (err < 0) {
				ALOGE("\"%s\": unable to get sampling frequency availability. (errno: %d)", iio_devices[i].name, err);
				goto st_hal_load_free_iio_channels;
			}

			err = device_iio_utils::get_available_scales(data[index].iio_sysfs_path,
								     &data[index].sa,
								     ST_sensors_supported[n].iio_sensor_type);
			if (err < 0)  {
				ALOGE("\"%s\": unable to get scale availability. (errno: %d)", iio_devices[i].name, err);
				goto st_hal_load_free_iio_channels;
			}

			if (data[index].sa.length > 0) {
				err = st_hal_set_fullscale(data[index].iio_sysfs_path, ST_sensors_supported[n].android_sensor_type,
								&data[index].sa, data[index].channels, data[index].num_channels);
				if (err < 0) {
					ALOGE("\"%s\": unable to set full scale. (errno: %d)", iio_devices[i].name, err);
					goto st_hal_load_free_iio_channels;
				}
			}
		}

		err = asprintf(&data[index].device_name, "%s", iio_devices[i].name);
		if (err < 0) {
			ALOGE("\"%s\": asprintf %d", iio_devices[i].name, err);
			goto st_hal_load_free_iio_channels;
		}

		err = asprintf(&data[index].android_name, "%s", ST_sensors_supported[n].android_name);
		if (err < 0) {
			ALOGE("\"%s\": asprintf %d", ST_sensors_supported[n].android_name, err);
			goto st_hal_load_free_device_name;
		}

		data[index].hw_fifo_len = device_iio_utils::get_hw_fifo_length(data[index].iio_sysfs_path);
		if (data[index].hw_fifo_len <= 0)
			data[index].hw_fifo_len = 1;

		data[index].sensor_type = ST_sensors_supported[n].android_sensor_type;
		data[index].dev_id = iio_devices[i].num;

		index++;

		continue;

st_hal_load_free_device_name:
	free(data[index].device_name);
st_hal_load_free_iio_channels:
	free(data[index].channels);
st_hal_load_free_iio_sysfs_path:
	free(data[index].iio_sysfs_path);
	}

	if (index == 0)
		ALOGE("No IIO sensors found into /sys/bus/iio/devices/ folder.");

	return index;
}

/*
 * st_hal_free_iio_devices_data() - Free iio devices data
 * @data: iio device data.
 * @num_devices: number of allocated devices.
 */
static void st_hal_free_iio_devices_data(STSensorHAL_iio_devices_data *data,
							unsigned int num_devices)
{
	unsigned int i;

	for (i = 0; i < num_devices; i++) {
		free(data[i].android_name);
		free(data[i].device_name);
		free(data[i].channels);
		free(data[i].iio_sysfs_path);
	}
}

static inline int st_hal_get_handle(STSensorHAL_data *hal_data, int handle)
{
	if (handle >= hal_data->last_handle)
		return hal_data->last_handle;
	else
		return handle;
}

/**
 * st_hal_dev_flush() - Flush sensor data
 * @dev: sensors device.
 * @handle: Android sensor handle.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_dev_flush(void *data, int handle)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;
	unsigned int index;

	IConsole &console { IConsole::getInstance() };
	console.info(std::string("flushing handle = ") + std::to_string(handle));

	if (handle > hal_data->last_handle) {
		return -EINVAL;
	}

	index = st_hal_get_handle(hal_data, handle);
	return hal_data->sensor_classes[index]->FlushData(handle, true);
}

#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_MARSHMALLOW_VERSION)
/**
 * st_hal_dev_inject_sensor_data() - Sensor data injection
 * @dev: sensors device.
 * @data: sensor event data to be injected.
 *
 * Return value: 0 on success, negative number on fail.
 */
__attribute__((unused)) static int st_hal_dev_inject_sensor_data(struct sensors_poll_device_1 *dev, const sensors_event_t *data)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)dev;

	/* check for operational parameter */
	if (data->sensor == -1)
		return -EINVAL;

	return hal_data->sensor_classes[data->sensor]->InjectSensorData(data);
}
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */

/**
 * st_hal_dev_batch() - Set sensor batch mode
 * @dev: sensors device structure.
 * @handle: Android sensor handle.
 * @flags: used for test the availability of batch mode.
 * @period_ns: time to batch (like setDelay(...)).
 * @timeout: 0 to disable batch mode.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_dev_batch(void *data, int handle,
				int flags, int64_t period_ns, int64_t timeout)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;
	unsigned int index = st_hal_get_handle(hal_data, handle);

	if (handle > hal_data->last_handle) {
		return -EINVAL;
	}

#if (CONFIG_ST_HAL_ANDROID_VERSION == ST_HAL_KITKAT_VERSION)
	if (((flags & SENSORS_BATCH_DRY_RUN) || (flags & SENSORS_BATCH_WAKE_UPON_FIFO_FULL)) && (timeout > 0)) {
		if (hal_data->sensor_classes[index]->GetMaxFifoLenght() > 0)
			return 0;
		else
			return -EINVAL;
	}
#else /* CONFIG_ST_HAL_ANDROID_VERSION */
	(void)flags;
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */

	return hal_data->sensor_classes[index]->SetDelay(handle, period_ns, timeout, true);
}

/**
 * st_hal_dev_poll() - Poll new sensors data
 * @dev: sensors device structure.
 * @data: data structure used to push data to the upper layer.
 * @count: maximum number of events in the same time.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_dev_poll(void *data, sensors_event_t *sdata, int count)
{
	unsigned int i;
	int err, read_size, remaining_event = count, event_read;
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;

	err = poll(hal_data->android_pollfd, hal_data->sensor_available, -1);
	if (err < 0)
		return 0;

	for (i = 0; i < hal_data->sensor_available; i++) {
		if (hal_data->android_pollfd[i].revents & POLLIN) {
			read_size = read(hal_data->android_pollfd[i].fd, sdata, remaining_event * sizeof(sensors_event_t));
			if (read_size <= 0)
				continue;

			event_read = (read_size / sizeof(sensors_event_t));
			remaining_event -= event_read;
			sdata += event_read;

			if (remaining_event == 0)
				return count;
		} else
			continue;
	}

	return (count - remaining_event);
}

/**
 * st_hal_dev_setDelay() - Set sensors polling rate
 * @dev: sensors device structure.
 * @handle: Android sensor handle.
 * @ns: polling rate value expressed in nanoseconds.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_dev_setDelay(void *data, int handle, int64_t ns)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;
	unsigned int index;

	index = st_hal_get_handle(hal_data, handle);
	return hal_data->sensor_classes[index]->SetDelay(handle, ns, 0, true);
}

/**
 * st_hal_dev_activate() - Enable or Disable sensors
 * @dev: sensors device structure.
 * @handle: Android sensor handle.
 * @enable: enable/ disable flag.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_dev_activate(void *data, int handle, int enabled)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;
	unsigned int index;

	if (handle > hal_data->last_handle) {
		return -EINVAL;
	}

	index = st_hal_get_handle(hal_data, handle);

	return  hal_data->sensor_classes[index]->Enable(handle, (bool)enabled, true);
}

/**
 * st_hal_dev_close() - Close device sensors module
 * @dev: sensors device structure.
 *
 * Return value: 0 on success, negative number on fail.
 */
__attribute__((unused)) static int st_hal_dev_close(struct hw_device_t *dev)
{
	unsigned int i;
	STSensorHAL_data *hal_data = (STSensorHAL_data *)dev;

	free(hal_data->data_threads);
	free(hal_data->events_threads);
	free(hal_data);

	for (i = 0; i < hal_data->sensor_available; i++)
		delete hal_data->sensor_classes[i];

	return 0;
}

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
/**
 * st_hal_read_private_data() - Read STSensorHAL private data
 * @priv_data: private data structure.
 *
 * Return value: 0 on success, negative number on fail.
 */
static int st_hal_read_private_data(struct st_hal_private_data *priv_data)
{
	int err;
	FILE *private_file;

	private_file = fopen(ST_HAL_PRIVATE_DATA_PATH, "r");
	if (!private_file)
		return -errno;

	err = fread(priv_data, sizeof(struct st_hal_private_data), 1, private_file);
	if (err <= 0) {
		fclose(private_file);
		return -errno;
	}

	fclose(private_file);

	return 0;
}

/**
 * st_hal_write_private_data() - Write STSensorHAL private data
 * @priv_data: private data structure.
 *
 * Return value: 0 on success, negative number on fail.
 */
static int st_hal_write_private_data(struct st_hal_private_data *priv_data)
{
	int err;
	FILE *private_file;

	private_file = fopen(ST_HAL_PRIVATE_DATA_PATH, "w");
	if (!private_file)
		return -errno;

	err = fwrite(priv_data, sizeof(struct st_hal_private_data), 1, private_file);
	if (err <= 0) {
		fclose(private_file);
		return -errno;
	}

	fclose(private_file);

	return 0;
}

/**
 * st_hal_set_default_private_data() - Set default STSensorHAL private data
 * @priv_data: private data structure.
 */
static void st_hal_set_default_private_data(struct st_hal_private_data *priv_data)
{
	memset(priv_data->calibration_last_modification, 0, ARRAY_SIZE(priv_data->calibration_last_modification) * sizeof(time_t));
}
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */

#ifdef CONFIG_ST_HAL_DIRECT_REPORT_SENSOR
/**
 * st_hal_dev_stop_all_direct_report() - Close all sensor for a channel handle
 *
 * @hal_data: Sensor HAL structure
 * @channel_handle: handle from st_hal_add_direct_channel()
 * @activeSensorList: active sensor list to be stopped (if null
 *                    do none)
 */
static int st_hal_dev_stop_all_direct_report(STSensorHAL_data *hal_data,
					     int channel_handle,
					     std::vector<int32_t> *activeSensorList)
{
	unsigned int handle;

	android::Mutex::Autolock autoLock(hal_data->mDirectChannelLock);

	if (mDirectChannel.find(channel_handle) ==
		mDirectChannel.end())
		return android::BAD_VALUE;

	std::vector<int32_t> sensorToStop;
	for (auto &it : mSensorToChannel) {
		auto j = it.second.find(channel_handle);
		if (j != it.second.end()) {
			it.second.erase(j);
			if (it.second.empty())
				sensorToStop.push_back(it.first);
		}
	}

	if (activeSensorList != nullptr)
		*activeSensorList = sensorToStop;

	for (auto sensor_handle : sensorToStop) {
		handle = st_hal_get_handle(hal_data, sensor_handle);
		hal_data->sensor_classes[handle]->Enable(handle, false, true);
		hal_data->sensor_classes[handle]->SetDelay(handle, 0, 0, true);
		ALOGD("Stopping Direct Report CH %d Sensor Handle %d",
		      channel_handle, handle);
	}

	return android::NO_ERROR;
}

/**
 * st_hal_dev_config_direct_report() - Android call this function to
 * configure a Direct Report Channel structure for a sensor
 *
 * @dev: poll device pointer
 * @sensor_handle: handle to sensor to configure on Direct Report Channel
 * @channel_handle: handle from st_hal_add_direct_channel()
 * @config: contains rate_level SENSOR_DIRECT_RATE_
 **/
static int st_hal_dev_config_direct_report(struct sensors_poll_device_1 *dev,
					   int sensor_handle, int channel_handle,
					   const sensors_direct_cfg_t *config)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)dev;
	int rate_level = config->rate_level;
	int64_t ns = 0LL;
	unsigned int handle;


	/* Check if need to disable direct report on all channel. */
	if (sensor_handle == -1 && rate_level == SENSOR_DIRECT_RATE_STOP) {
		/* All sensor associated to channel_handle MUST be stopped. */
		return st_hal_dev_stop_all_direct_report(hal_data, channel_handle,
							 nullptr);
	}

	if (rate_level > SENSOR_DIRECT_RATE_VERY_FAST) {
		ALOGW("Rate Level too high %d for channel %d",
		      channel_handle, rate_level);
		rate_level = SENSOR_DIRECT_RATE_VERY_FAST;
	}

	android::Mutex::Autolock autoLock(hal_data->mDirectChannelLock);

	/* Manage direct channel data structure. */
	auto i = mDirectChannel.find(channel_handle);
	if (i == mDirectChannel.end()) {
		ALOGE("Invalid Direct Channel %d", channel_handle);
		return 0;
	}
	if (i->second == NULL) {
		ALOGE("mDirectChannel is NULL, not sharable resource");

		return 0;
	}

	auto j = mSensorToChannel.find(sensor_handle);
	if (j == mSensorToChannel.end()) {
		ALOGD("Adding Sensor Handle %d to Direct Channel %d",
		      sensor_handle, channel_handle);
		/* Dynamicaly emplace a new map of mSensorToChannel. */
		mSensorToChannel.emplace(sensor_handle,
			std::unordered_map<int32_t, int32_t>());
		j = mSensorToChannel.find(sensor_handle);
	}

	j->second.erase(channel_handle);
	if (rate_level != SENSOR_DIRECT_RATE_STOP)
		j->second.insert(std::make_pair(channel_handle, rate_level));

	/*
	 * From Android Doc:
	 *  SENSOR_DIRECT_RATE_STOP - Sensor stopped (no event output).
	 *  SENSOR_DIRECT_RATE_NORMAL - Sensor operates at nominal rate of 50Hz.
	 *  SENSOR_DIRECT_RATE_FAST - Sensor operates at nominal rate of 200Hz.
	 *  SENSOR_DIRECT_RATE_VERY_FAST - Sensor operates at nominal rate of 800Hz.
	 *
	 * There is a direct correlation from Direct rate value to sample rate of
	 * sensor.
	 */
	switch(rate_level) {
	case SENSOR_DIRECT_RATE_NORMAL:
		ns = FREQUENCY_TO_NS(50);
		break;
	case SENSOR_DIRECT_RATE_FAST:
		ns = FREQUENCY_TO_NS(200);
		break;
	case SENSOR_DIRECT_RATE_VERY_FAST:
		ns = FREQUENCY_TO_NS(800);
		break;
	default:
		ALOGW("Invalid rate level (%d)", rate_level);
		break;
	}

	/* Associate an existing Channel Report to sensor. */
	handle = st_hal_get_handle(hal_data, sensor_handle);
	hal_data->sensor_classes[handle]->mDirectChannel = std::move(i->second);
	hal_data->sensor_classes[handle]->SetChannelHandle(channel_handle);
	hal_data->sensor_classes[handle]->Enable(handle, true, true);
	hal_data->sensor_classes[handle]->SetDelay(handle, ns, 0, true);
	hal_data->sensor_classes[handle]->SetChannelDatarate(rate_level);
	ALOGD("Setting Direct Channel %d Sensor(%d) %d to rate %" PRId64 " ns",
	      channel_handle, sensor_handle, handle, ns);

	return sensor_handle;
}

/**
 * st_hal_add_direct_channel() - Add a Direct Channel
 * @mem: shared memory information pointer for a direct channel
 * @return: > 0 channel_handle for new created Direct Channel
 * 	    NO_MEMORY, INVALID_OPERATION if error
 *
 * TODO: Unsupported Hardware Buffer type GRALLOC
 **/
static int st_hal_add_direct_channel(struct sensors_poll_device_1 *dev,
                                     const struct sensors_direct_mem_t *mem)
{
	std::unique_ptr<DirectChannelBase> ch;
	int ret = android::NO_MEMORY;
	STSensorHAL_data *hal_data = (STSensorHAL_data *)dev;

	switch(mem->type) {
	case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
		ch = std::make_unique<AshmemDirectChannel>(mem);
		break;
	case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
		ch = std::make_unique<GrallocDirectChannel>(mem);
		break;
	default:
		ret = android::INVALID_OPERATION;
		break;
	}

	if (ch->isValid()) {
		android::Mutex::Autolock autoLock(hal_data->mDirectChannelLock);
		ret = hal_data->mDirectChannelHandle++;
		/* Associate channel_handle to Direct Channel buffer. */
		mDirectChannel.insert(std::make_pair(ret, std::move(ch)));
		ALOGD("Direct Channel type ASHMEM created (%d)", ret);
	} else {
		ret = ch->getError();
		ALOGW("Direct channel object(type:%d) has error %d upon init",
		      mem->type, ret);
	}

	return ret;
}

/**
 * st_hal_dev_remove_direct_channel() - Remove a Direct Channel
 * @channel_handle: handle from st_hal_add_direct_channel()
 * TODO: Unsupported Hardware Buffer type GRALLOC
 **/
static int st_hal_dev_remove_direct_channel(struct sensors_poll_device_1 *dev,
                                            int channel_handle)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)dev;
	unsigned int handle;

	/* Check if there are sensors enabled for Direct Report. */
	for (auto &it : mSensorToChannel) {
		auto j = it.second.find(channel_handle);
		if (j != it.second.end()) {
			it.second.erase(j);
			handle = st_hal_get_handle(hal_data, it.first);
			hal_data->sensor_classes[handle]->mDirectChannelLock.lock();
			hal_data->sensor_classes[handle]->SetDelay(handle, 0ll, 0, true);
			hal_data->sensor_classes[handle]->Enable(handle, false, true);
			mDirectChannel.find(channel_handle)->second =
				std::move(hal_data->sensor_classes[handle]->mDirectChannel);
			hal_data->sensor_classes[handle]->mDirectChannelLock.unlock();
			ALOGD("Stopping Direct Report Sensor CH %d Handle %d",
			      it.first, handle);
		}
	}

	/* Remove the channel record. */
	android::Mutex::Autolock autoLock(hal_data->mDirectChannelLock);
	mDirectChannel.erase(channel_handle);

	return android::NO_ERROR;
}

/**
 * st_hal_dev_register_direct_channel() - Android call this function to
 * allocate a new Direct Report Channel structure
 *
 * @dev: poll device pointer
 * @mem: shared memory information pointer for a direct channel
 * @channel_handle: handle from st_hal_add_direct_channel()
 **/
static int st_hal_dev_register_direct_channel(struct sensors_poll_device_1 *dev,
					      const struct sensors_direct_mem_t* mem,
					      int channel_handle)
{
	if (mem)
		return st_hal_add_direct_channel(dev, mem);

	return st_hal_dev_remove_direct_channel(dev, channel_handle);
}
#endif /* CONFIG_ST_HAL_DIRECT_REPORT_SENSOR */

//static STSensorHAL_data *hal_data;

/**
 * open_sensors() - Open sensor device
 * see Android documentation.
 *
 * Return value: 0 on success, negative number on fail.
 */
int st_hal_open_sensors(void **data)
{
	int sensor_class_valid_num = 0;
	int sensor_class_num_data = 0, j = 0;
	int sensor_class_num_event = 0, k = 0;
#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
	struct st_hal_private_data private_data;
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
	bool sensor_class_valid[ST_HAL_IIO_MAX_DEVICES];
	int type_index;
	SensorBase *sensor_class, *temp_sensor_class[ST_HAL_IIO_MAX_DEVICES];
	STSensorHAL_iio_devices_data iio_devices_data[ST_HAL_IIO_MAX_DEVICES];
	int err = -ENODEV, i, c, device_found_num, classes_available = 0, n = 0;
	IConsole &console { IConsole::getInstance() };

	*data = malloc(sizeof(STSensorHAL_data));
	if (!*data)
		return -ENOMEM;

	STSensorHAL_data *hal_data = (STSensorHAL_data *)*data;

	memset(hal_data, 0, sizeof(STSensorHAL_data));
	hal_data->sensor_available = 0;

	mkdir(ST_HAL_DATA_PATH, S_IRWXU);

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
	err = st_hal_read_private_data(&private_data);
	if (err < 0) {
		ALOGE("Failed to read private data. First boot?");
		st_hal_set_default_private_data(&private_data);
	}
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */

	console.info("load IIO devices");

	device_found_num = st_hal_load_iio_devices_data(iio_devices_data);
	if (device_found_num < 0) {
		console.error("no sensors found");
		err = device_found_num;
		goto free_hal_data;
	}

	for (i = 0; i < device_found_num; i++) {
#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
		sensor_class = st_hal_create_class_sensor(&iio_devices_data[i], classes_available + 1, &private_data);
#else /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
		sensor_class = st_hal_create_class_sensor(&iio_devices_data[i], classes_available + 1, NULL);
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */
		if (!sensor_class) {
			ALOGE("\"%s\": failed to create HW sensor class.", iio_devices_data[i].device_name);
			continue;
		}

#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_VERBOSE)
	ALOGD("\"%s\": created HW class instance, handle: %d (sensor type: %d).", sensor_class->GetName(), sensor_class->GetHandle(), sensor_class->GetType());
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */

		temp_sensor_class[classes_available] = sensor_class;
		sensor_class_valid[classes_available] = true;
		sensor_class_valid_num++;
		if (sensor_class->hasDataChannels())
			sensor_class_num_data++;

		if (sensor_class->hasEventChannels())
			sensor_class_num_event++;

		classes_available++;
	}

#ifdef CONFIG_ST_HAL_FACTORY_CALIBRATION
	err = st_hal_write_private_data(&private_data);
	if (err < 0)
		ALOGE("Failed to write private data.");
#endif /* CONFIG_ST_HAL_FACTORY_CALIBRATION */

	for (i = 0; i < (int)ARRAY_SIZE(ST_virtual_sensors_list); i++) {
		sensor_class = st_hal_create_virtual_class_sensor(ST_virtual_sensors_list[i].android_sensor_type, classes_available + 1);
		if (!sensor_class) {
			ALOGE("Failed to create SW sensor class (sensor type: %d).", ST_virtual_sensors_list[i].android_sensor_type);
			continue;
		}

#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_VERBOSE)
		if (sensor_class->GetType() < SENSOR_TYPE_ST_CUSTOM_NO_SENSOR)
			ALOGD("\"%s\": created SW class instance, handle: %d (sensor type: %d).", sensor_class->GetName(), sensor_class->GetHandle(), sensor_class->GetType());
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */

		temp_sensor_class[classes_available] = sensor_class;
		sensor_class_valid[classes_available] = true;
		sensor_class_valid_num++;
		if (sensor_class->hasDataChannels())
			sensor_class_num_data++;

		if (sensor_class->hasEventChannels())
			sensor_class_num_event++;

		classes_available++;
	}

	for (i = 0; i < classes_available; i++) {
		const std::vector<STMSensorType> &type_dependencies = temp_sensor_class[i]->GetDepenciesTypeList();
		type_index = 0;

		for (auto dependecyType : type_dependencies) {
			if (dependecyType == STMSensorType::INTERNAL_LIB_TYPE) {
				continue;
			}

			err = 0;

			for (c = 0; c < classes_available; c++) {
				if ((dependecyType == temp_sensor_class[c]->GetType()) && (sensor_class_valid[c])) {
					err = temp_sensor_class[i]->AddSensorDependency(temp_sensor_class[c]);
					break;
				}
			}

			if ((c == classes_available) || (err < 0)) {
				ALOGE("\"%s\": failed to add dependency (sensor type dependency: %d).", temp_sensor_class[i]->GetName(), type_dependencies[type_index]);

				while (type_index > 0) {
					type_index--;

					for (c = 0; c < classes_available; c++) {
						if ((type_dependencies[type_index] == temp_sensor_class[c]->GetType()) && (sensor_class_valid[c])) {
							temp_sensor_class[i]->RemoveSensorDependency(temp_sensor_class[c]);
							break;
						}
					}
				}

				sensor_class_valid_num--;
				sensor_class_valid[i] = false;
				goto failed_to_add_dependency;
			}

			type_index++;
		}

failed_to_add_dependency:
		continue;
	}

	for (i = 0; i < classes_available; i++) {
		if (sensor_class_valid[i]) {
			err = temp_sensor_class[i]->CustomInit();
			if (err < 0) {
				sensor_class_valid_num--;
				sensor_class_valid[i] = false;
			} else
				hal_data->sensor_classes[temp_sensor_class[i]->GetHandle()] = temp_sensor_class[i];
		}
	}

	hal_data->data_threads = (pthread_t *)malloc(sensor_class_num_data * sizeof(pthread_t *));
	if (!hal_data->data_threads) {
		err = -ENOMEM;
		goto free_sensor_t_list;
	}

	hal_data->events_threads = (pthread_t *)malloc(sensor_class_num_event * sizeof(pthread_t *));
	if (!hal_data->events_threads) {
		err = -ENOMEM;
		goto free_data_threads;
	}

	for (i = 0; i < classes_available; i++) {
		if (sensor_class_valid[i]) {
			if (temp_sensor_class[i]->hasDataChannels()) {
				err = pthread_create(&hal_data->data_threads[j], NULL, &SensorBase::ThreadDataWork, (void *)temp_sensor_class[i]);
				if (err < 0) {
					ALOGE("%s: Failed to create IIO data pThread.", temp_sensor_class[i]->GetName());
					sensor_class_valid[i] = false;
					continue;
				}
				j++;
			}

			if (temp_sensor_class[i]->hasEventChannels()) {
				err = pthread_create(&hal_data->events_threads[k], NULL, &SensorBase::ThreadEventsWork, (void *)temp_sensor_class[i]);
				if (err < 0) {
					ALOGE("%s: Failed to create IIO events pThread.", temp_sensor_class[i]->GetName());
					sensor_class_valid[i] = false;
					continue;
				}
				k++;
			}

			const SensorBase::Info &info = hal_data->sensor_classes[temp_sensor_class[i]->GetHandle()]->getSTMSensor();

			auto sensor = std::make_unique<STMSensor>(info.name,
								  info.vendor,
								  info.handle,
								  info.version,
								  info.type,
								  info.maxRange,
								  info.resolution,
								  info.power,
								  info.minRateHz,
								  info.maxRateHz,
								  info.fifoRsvdCount,
								  info.fifoMaxCount,
								  info.wakeUp);

			hal_data->sensorList.addSensor(*sensor);
			if (sensor->getType() == STMSensorType::INTERNAL_LIB_TYPE) {
				continue;
			}
			hal_data->android_pollfd[n].events = POLLIN;
			hal_data->android_pollfd[n].fd = hal_data->sensor_classes[temp_sensor_class[i]->GetHandle()]->GetFdPipeToRead();

			hal_data->last_handle = temp_sensor_class[i]->GetHandle();
			n++;
		} else
			delete temp_sensor_class[i];
	}

#ifdef CONFIG_ST_HAL_DYNAMIC_SENSOR
	hal_data->last_handle++;
	hal_data->sensor_classes[hal_data->last_handle] = new DynamicSensorProxy(hal_data, n,
										 hal_data->last_handle);
	n++;
#endif /* CONFIG_ST_HAL_DYNAMIC_SENSOR */

	hal_data->sensor_available = n;

	st_hal_free_iio_devices_data(iio_devices_data, device_found_num);

#ifdef CONFIG_ST_HAL_HAS_SELFTEST_FUNCTIONS
	hal_data->self_test = new SelfTest(hal_data);
	if (!hal_data->self_test->IsValidClass()) {
		ALOGE("Failed to allocate SelfTest class.");
	}
#endif /* CONFIG_ST_HAL_HAS_SELFTEST_FUNCTIONS */

#if (CONFIG_ST_HAL_DEBUG_LEVEL >= ST_HAL_DEBUG_INFO)
	ALOGD("%d sensors available and ready.", hal_data->sensor_available);
#endif /* CONFIG_ST_HAL_DEBUG_LEVEL */

#ifdef CONFIG_ST_HAL_DIRECT_REPORT_SENSOR
	hal_data->mDirectChannelHandle = 1;
#endif /* CONFIG_ST_HAL_DIRECT_REPORT_SENSOR */

	return 0;

free_data_threads:
	free(hal_data->data_threads);
free_sensor_t_list:
	for (i = 0; i < classes_available; i ++)
		delete temp_sensor_class[i];

	st_hal_free_iio_devices_data(iio_devices_data, device_found_num);
free_hal_data:
	free(hal_data);

	return err;
}

/**
 * get_sensors_list() - Get sensors list
 * @module: hardware specific informations.
 * @list: sensors list.
 *
 * Return value: number of sensors available.
 */
STMSensorsList& st_hal_get_sensors_list(void *data)
{
	STSensorHAL_data *hal_data = (STSensorHAL_data *)data;

	return hal_data->sensorList;
};

#if (CONFIG_ST_HAL_ANDROID_VERSION >= ST_HAL_MARSHMALLOW_VERSION)
/**
 * st_hal_set_operation_mode() - Set HAL mode
 * @mode: HAL mode.
 *
 * Return value: 0 (supported), negative number if error.
 */
__attribute__((unused)) static int st_hal_set_operation_mode(unsigned int mode)
{
	int err;
	bool enable_injection = false;
	STSensorHAL_data *hal_data = (STSensorHAL_data *)&mode;

	switch (mode) {
	case SENSOR_HAL_NORMAL_MODE:
		enable_injection = false;
		break;

	case SENSOR_HAL_DATA_INJECTION_MODE:
		enable_injection = true;
		break;

	default:
		return -EPERM;
	}

	for (auto sensor : hal_data->sensorList.getList()) {
		err = hal_data->sensor_classes[sensor.getHandle()]->InjectionMode(enable_injection);
		if (err < 0) {
			ALOGE("Failed to set HAL operation mode. (errno=%d)", err);
			goto rollback_operation_mode;
		}
	}

	return 0;

rollback_operation_mode:
	for (auto sensor : hal_data->sensorList.getList()) {
		err = hal_data->sensor_classes[sensor.getHandle()]->InjectionMode(!enable_injection);
		if (err < 0) {
			ALOGE("Failed to set HAL operation mode. (errno=%d)", err);
			goto rollback_operation_mode;
		}
	}

	return -EINVAL;
}
#endif /* CONFIG_ST_HAL_ANDROID_VERSION */
